﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Amazon;
using Amazon.S3;
using Amazon.S3.Model;
using System.Diagnostics;
using System.Net;
using System.Diagnostics.CodeAnalysis;

namespace AWSS3ToAzureBlob
{
    [ExcludeFromCodeCoverage]
    class AWSS3Facade : IAWSS3Facade
    {
        private AmazonS3Client _client = null;
        private string _awsS3Bucket = null;
        private int _expiryMinutes = 0;

        public bool Initialize(string awsAccessKeyId, 
            string awsSecretAccessKey, 
            string awsS3Bucket,
            int expiryMinutes)
        {
            bool returnValue = false;

            try
            {
                _awsS3Bucket = awsS3Bucket;
                _expiryMinutes = expiryMinutes;

                _client = new AmazonS3Client(awsAccessKeyId,
                    awsSecretAccessKey,
                    RegionEndpoint.USEast1);

                returnValue = ValidateAccessToBucket();
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.Message);
            }

            return returnValue;
        }

        private bool ValidateAccessToBucket()
        {
            GetBucketLocationRequest request = new GetBucketLocationRequest()
            {
                BucketName = _awsS3Bucket
            };

            var response = _client.GetBucketLocation(request);

            if (response.HttpStatusCode == HttpStatusCode.OK)
            {
                return true;
            }

            return false;
        }

        public string[] ListKeys()
        {
            ListObjectsRequest request = new ListObjectsRequest()
            {
                BucketName = _awsS3Bucket
            };

            List<string> keys = new List<string>();

            ListObjectsResponse response;
            do
            {
                response = _client.ListObjects(request);
                foreach (S3Object obj in response.S3Objects)
                {
                    if (!IsFolder(obj))
                    {
                        keys.Add(obj.Key);    
                    }
                }

                // Set the marker property
                request.Marker = response.NextMarker;
            } while (response.IsTruncated);

            return keys.ToArray();
        }

        private static bool IsFolder(S3Object obj)
        {
            return obj.Key.EndsWith("/");
        }

        public string GenerateUrl(string key)
        {
            GetPreSignedUrlRequest request = new GetPreSignedUrlRequest()
            {
                BucketName = _awsS3Bucket,
                Key = key,
                Protocol = Protocol.HTTPS,
                Expires = DateTime.Now.AddMinutes(_expiryMinutes)
            };

            return _client.GetPreSignedURL(request);
        }
    }
}